﻿

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using SharpDX;
using SharpDX.Direct2D1;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
using SharpDX.DXGI;
using AlphaMode = SharpDX.Direct2D1.AlphaMode;
using Bitmap = SharpDX.Direct2D1.Bitmap;
using Device = SharpDX.Direct3D11.Device;
using Device1 = SharpDX.Direct3D11.Device1;
using PixelFormat = SharpDX.Direct2D1.PixelFormat;
using RectangleF = SharpDX.RectangleF;

namespace DirecxPictureBox
{
    public partial class DroneVideo : UserControl
    {
        public double Tangag = 0;
        public double Kren = 0;



        public DroneVideo()
        {

            InitializeComponent();
            Initdx();
            _lsize = ClientSize;
        }

        private readonly object _lo = new object();
        private bool draw = false;

        public bool Bootstrap ;
        public bool Landed;
        public bool Takeoff;
        public bool Flying;
        public bool Hovering;
        public bool Landing;
        public bool Emergency;
        public bool Wind;
        public System.Drawing.Rectangle Rect;
        public string Mode;

        string state()
        {
            string s = "";
            if (Bootstrap)
                s += "Загрузка ";
            if (Landed)
                s += "Земля ";
            if (Takeoff)
                s += "Взлет ";
            if (Flying)
                s += "Полет ";
            if (Hovering)
                s += "Парение ";
            if (Landing)
                s += "Посадка ";
            if (Emergency)
                s += "Авария ";
            if (Wind)
                s += "Ветер ";
            return s;
        }

        public void Refresh()
        {


            if (!draw)
            { draw = true;
                try { 
               
                    lock (_lo)
                    {


                        _d2DContext.Target = _d2DTarget;
                        _d2DContext.BeginDraw();
                        _d2DContext.Clear(new Color4(0, 0, 0, 0));
                        int _w = _bitmap != null ? Convert.ToInt32( _bitmap.Size.Width) : ClientSize.Width;
                        int _h = _bitmap != null ?  Convert.ToInt32(_bitmap.Size.Height) : ClientSize.Height;

                        RectangleF rect =  new RectangleF(0, 0, _w, _h);
                        if (SizeMode == PictureBoxSizeMode.StretchImage)
                            rect = new RectangleF(0, 0, _d2DContext.Size.Width, _d2DContext.Size.Height);

                        if (SizeMode == PictureBoxSizeMode.CenterImage)
                            rect = new RectangleF(_d2DContext.Size.Width/2 - _w/2,
                                _d2DContext.Size.Height/2 - _h/2, _w,
                                _h);

                        if (SizeMode == PictureBoxSizeMode.Normal)
                            rect = new RectangleF(0, 0, _w, _h);

                        if (SizeMode == PictureBoxSizeMode.Zoom)
                        {
                            double kw = Convert.ToDouble(_w)/Width;
                            double kh = Convert.ToDouble(_h)/Height;
                            double k = 1/Math.Max(kw, kh);
                            rect = new RectangleF(_d2DContext.Size.Width/2 - Convert.ToInt32(_w*k/2),
                                _d2DContext.Size.Height/2 - Convert.ToInt32(_h*k/2),
                                Convert.ToInt32(k*_w), Convert.ToInt32(k*_h));


                        }
                        Rect = new System.Drawing. Rectangle(Convert.ToInt32(rect.X), Convert.ToInt32(rect.Y), Convert.ToInt32(rect.Width), Convert.ToInt32(rect.Height));
                        if (_bitmap!=null)
                        _d2DContext.DrawBitmap(_bitmap, rect, 1, BitmapInterpolationMode.Linear);
                    
                        for (double i = -90; i <= 90; i += 2.5)
                            if (Math.Abs(i) < 15 || i%5 == 0)
                                driveLine(i, rect);
                        drivealt(Altitude, rect);
                        drawProc(Procent, rect);
                        drwKompas(Yau, rect);
                        _d2DContext.DrawEllipse(
                            new Ellipse(new Vector2(rect.Left + rect.Width/2, rect.Top + rect.Height/2), rect.Height/70,
                                rect.Height/70), TRBrshW, rect.Height/100);
                        _d2DContext.DrawLine(
                            new Vector2(rect.Left + rect.Width/2 - rect.Height/80, rect.Top + rect.Height/2),
                            new Vector2(rect.Left + rect.Width/2 - rect.Height/20, rect.Top + rect.Height/2), TRBrshW,
                            rect.Height/100);
                        _d2DContext.DrawLine(
                            new Vector2(rect.Left + rect.Width/2 + rect.Height/80, rect.Top + rect.Height/2),
                            new Vector2(rect.Left + rect.Width/2 + rect.Height/20, rect.Top + rect.Height/2), TRBrshW,
                            rect.Height/100);

                     

                        _d2DContext.FillRectangle(new RectangleF(rect.Left, rect.Top, rect.Width, rect.Height/30),
                            TRBrshB);
                        if (Rec >700)
                        {
                        _d2DContext.FillEllipse(
                            new Ellipse(new Vector2(rect.Left + rect.Height/30, rect.Top + rect.Height/60),
                                rect.Height/100, rect.Height/100), TRBrshRR);  
                        }
                      if (Rec>200)
                        _d2DContext.DrawText((Rec >700?"Rec":"USB") +"("+UsbTime/60+"мин)",
                                new SharpDX.DirectWrite.TextFormat(_wrireFactory, "Arial", rect.Height/35),
                                new RectangleF(rect.Left + rect.Height/20, rect.Top, rect.Width/5, rect.Height/30),
                                Rec > 700 ? TRBrshRR : TRBrshWW);
                     

                        _d2DContext.DrawText(_h + "p",
                            new SharpDX.DirectWrite.TextFormat(_wrireFactory, "Arial", rect.Height/35),
                            new RectangleF(rect.Left + rect.Width/7, rect.Top, rect.Width/20, rect.Height/30),
                            TRBrshWW);


                        _d2DContext.DrawText(Mode,
                            new SharpDX.DirectWrite.TextFormat(_wrireFactory, "Arial", rect.Height / 35),
                            new RectangleF(rect.Left + rect.Width / 5, rect.Top, rect.Width / 5, rect.Height / 30),
                            TRBrshWW);

                        _d2DContext.DrawText(state(),
                          new SharpDX.DirectWrite.TextFormat(_wrireFactory, "Arial", rect.Height / 35),
                          new RectangleF(rect.Left + rect.Width *0.47f, rect.Top, rect.Width / 3, rect.Height / 30),
                          TRBrshWW);
                        for (int i = 1; i < 6; i++)
                            if (i <= WiFi)
                                _d2DContext.DrawLine(
                                    new Vector2(rect.Left + rect.Width*0.9f + i*rect.Height/90,
                                        rect.Top + rect.Height/35),
                                    new Vector2(rect.Left + rect.Width*0.9f + i*rect.Height/90,
                                        rect.Top + (rect.Height/35)*(1 - 0.18f*i)),
                                    TRBrshWW, rect.Height/100);
                        _d2DContext.DrawText(Battarey + "%",
                            new SharpDX.DirectWrite.TextFormat(_wrireFactory, "Arial", rect.Height/35),
                            new RectangleF(rect.Left + rect.Width*0.95f, rect.Top, rect.Width/20, rect.Height/30),
                            Battarey > 20 ? TRBrshGG : TRBrshRR);


                        _d2DContext.DrawText((FlyTime / 60) + "." + (FlyTime % 60) + " | " + (EndTime / 60) + "." + (EndTime % 60) + " | "  + (TotalTime / 60) + "." + (TotalTime % 60),
                     new SharpDX.DirectWrite.TextFormat(_wrireFactory, "Arial", rect.Height / 35),
                     new RectangleF(rect.Left + rect.Width * 0.7f, rect.Top, rect.Width / 5, rect.Height / 30),
                     TRBrshW);
                        _d2DContext.EndDraw();

                  

                        _swapChain.Present(1, PresentFlags.None);
                    }
                   
                } catch{}
                draw = false;
            }

        }

        void driveLine(double angle, RectangleF rect)
        {
            float w = 0;
            if (angle == 0)
                w = rect.Height / 3;
            else
            {
                if (angle % 5 == 0)
                    w = rect.Height / 6;
                else
                    w = rect.Height / 10;
            }

            double y = (rect.Height / 2 * ((Tangag + (angle / 180.0 * Math.PI)) / 0.227)) * Math.Cos(Kren);
            double x = (rect.Height / 2 * ((Tangag + (angle / 180.0 * Math.PI)) / 0.227)) * Math.Sin(Kren);
            float x1 = rect.Left + (float)((rect.Width / 2 - w * (Math.Cos(Kren))) + x);
            float x2 = rect.Left + (float)(rect.Width / 2 + x + (w * (Math.Cos(Kren))));
            float y1 = rect.Top + (float)(rect.Top + rect.Height / 2 + y + (w * Math.Sin(Kren)));
            float y2 = rect.Top + (float)(rect.Top + rect.Height / 2 + y - (w * Math.Sin(Kren)));

            if (Math.Abs(y) < rect.Height * 0.4 && Math.Abs(x) < rect.Width * 0.25)
            {
                if (angle == 0)
                    _d2DContext.DrawLine(new Vector2(x1, y1), new Vector2(x2, y2), TRBrshWW, 5);
                else
                {
                    _d2DContext.DrawLine(new Vector2(x1, y1), new Vector2(x2, y2), angle < 0 ? TRBrshGG : TRBrshRR,
                        angle % 5 == 0 ? 3 : 2);
                    if (angle % 5 == 0)
                    {
                        _d2DContext.DrawLine(new Vector2(x2, y2),
                            new Vector2(x2 + (float)(w * 0.1 * Math.Sin(Kren) * (angle < 0 ? 1 : -1)),
                                y2 + (float)(w * 0.1 * Math.Cos(Kren) * (angle < 0 ? 1 : -1))), angle < 0 ? TRBrshGG : TRBrshRR,
                            angle % 5 == 0 ? 3 : 2);
                        _d2DContext.DrawLine(new Vector2(x1, y1),
                            new Vector2(x1 + (float)(w * 0.1 * Math.Sin(Kren) * (angle < 0 ? 1 : -1)),
                                y1 + (float)(w * 0.1 * Math.Cos(Kren) * (angle < 0 ? 1 : -1))), angle < 0 ? TRBrshGG : TRBrshRR,
                            angle % 5 == 0 ? 3 : 2);
                    }
                }


            }

        }

        public int Altitude = 0;
        public int FlyTime = 0;
        public int EndTime= 0;
        public int TotalTime = 0;
        public int Procent = 0;
        public float Yau = 0;
        public int Battarey = 0;
        public int WiFi = 5;
        public int Rec = 0;
        public long State = 0;
        public int UsbTime = 0;
        public float[] Speed;

        void drivealt(int cm, RectangleF rect)
        {

            float x = rect.Left + rect.Width / 5;
            float y1 = rect.Top + rect.Height * 0.25f;
            float y2 = rect.Top + rect.Height * 0.75f;
            _d2DContext.DrawLine(new Vector2(x, y1), new Vector2(x, y2), TRBrshW, 1);
            _d2DContext.DrawLine(new Vector2(x - rect.Width / 40, y1), new Vector2(x, y1), TRBrshW, 2);
            _d2DContext.DrawLine(new Vector2(x - rect.Width / 40, y2), new Vector2(x, y2), TRBrshW, 2);
            for (float i = 0.05f; i < 1; i += 0.05f)
            {
                if (Math.Abs(i % 0.1f) < 0.001)
                    _d2DContext.DrawLine(new Vector2(x - rect.Width / 50, y1 + i * (y2 - y1)), new Vector2(x, y1 + i * (y2 - y1)), TRBrshW, 2);
                else
                    _d2DContext.DrawLine(new Vector2(x - rect.Width / 60, y1 + i * (y2 - y1)), new Vector2(x, y1 + i * (y2 - y1)), TRBrshW, 2);
            }
            string s = "1м";
            if (cm > 100) s = "10м";
            if (cm > 1000) s = "50м";

            string v = cm + "см";
            if (cm > 100) v = cm / 100.0f + "м";
            float yt = (y2 - y1) * (1 - (cm / 100.0f));
            if (cm > 100)
                yt = (y2 - y1) * (1 - (cm / 1000.0f));
            if (cm > 1000)
                yt = (y2 - y1) * (1 - (cm / 5000.0f));
            _d2DContext.DrawLine(new Vector2(x - rect.Width / 10, y1 - rect.Width / 80 + yt),
                new Vector2(x - rect.Width / 35, y1 - rect.Width / 80 + yt), TRBrshWW, 4);
            _d2DContext.DrawLine(new Vector2(x - rect.Width / 10, y1 + rect.Width / 80 + yt),
               new Vector2(x - rect.Width / 35, y1 + rect.Width / 80 + yt), TRBrshWW, 4);
            _d2DContext.DrawLine(new Vector2(x - rect.Width / 10, y1 + rect.Width / 80 + yt),
              new Vector2(x - rect.Width / 10, y1 - rect.Width / 80 + yt), TRBrshWW);

            _d2DContext.DrawLine(new Vector2(x - rect.Width / 35, y1 + rect.Width / 80 + yt),
             new Vector2(x - rect.Width / 50, y1 + yt), TRBrshWW, 4);
            _d2DContext.DrawLine(new Vector2(x - rect.Width / 35, y1 - rect.Width / 80 + yt),
          new Vector2(x - rect.Width / 50, y1 + yt), TRBrshWW, 4);

            _d2DContext.DrawText(s,
                 new SharpDX.DirectWrite.TextFormat(_wrireFactory, "Arial", rect.Width / 50), new RectangleF(x - rect.Width / 30, y1 - rect.Width / 40, 100, 10),
                 TRBrshW);
            _d2DContext.DrawText(v,
         new SharpDX.DirectWrite.TextFormat(_wrireFactory, "Arial", rect.Width / 40), new RectangleF(x - rect.Width / 10, y1 - rect.Width / 70 + yt, rect.Width / 3, 10),
         TRBrshWW);



        }

        void drawProc(int proc, RectangleF rect)
        {

            float x = rect.Left + rect.Width - rect.Width / 5;
            float y1 = rect.Top + rect.Height * 0.25f;
            float y2 = rect.Top + rect.Height * 0.75f;
            _d2DContext.DrawLine(new Vector2(x, y1), new Vector2(x, y2), TRBrshW, 1);
            _d2DContext.DrawLine(new Vector2(x + rect.Width / 40, y1), new Vector2(x, y1), TRBrshW, 1);
            _d2DContext.DrawLine(new Vector2(x + rect.Width / 40, y2), new Vector2(x, y2), TRBrshW, 1);
            for (float i = 0.05f; i < 1; i += 0.05f)
            {
                if (Math.Abs(i % 0.1f) < 0.001)
                    _d2DContext.DrawLine(new Vector2(x + rect.Width / 50, y1 + i * (y2 - y1)), new Vector2(x, y1 + i * (y2 - y1)), TRBrshW, 1);
                else
                    _d2DContext.DrawLine(new Vector2(x + rect.Width / 60, y1 + i * (y2 - y1)), new Vector2(x, y1 + i * (y2 - y1)), TRBrshW, 1);
            }
            string s = "100%";
            float yt = (y2 - y1) * (1 - proc / 100.0f);

            _d2DContext.DrawLine(new Vector2(x + rect.Width / 12, y1 - rect.Width / 80 + yt),
                new Vector2(x + rect.Width / 35, y1 - rect.Width / 80 + yt), TRBrshW);
            _d2DContext.DrawLine(new Vector2(x + rect.Width / 12, y1 + rect.Width / 80 + yt),
               new Vector2(x + rect.Width / 35, y1 + rect.Width / 80 + yt), TRBrshW);
            _d2DContext.DrawLine(new Vector2(x + rect.Width / 12, y1 + rect.Width / 80 + yt),
              new Vector2(x + rect.Width / 12, y1 - rect.Width / 80 + yt), TRBrshW);

            _d2DContext.DrawLine(new Vector2(x + rect.Width / 35, y1 + rect.Width / 80 + yt),
             new Vector2(x + rect.Width / 50, y1 + yt), TRBrshW);
            _d2DContext.DrawLine(new Vector2(x + rect.Width / 35, y1 - rect.Width / 80 + yt),
          new Vector2(x + rect.Width / 50, y1 + yt), TRBrshW);


            _d2DContext.DrawText(proc + "%",
         new SharpDX.DirectWrite.TextFormat(_wrireFactory, "Arial", rect.Width / 50), new RectangleF(x + rect.Width / 30, y1 - rect.Width / 80 + yt, 100, 10),
         TRBrshW);



        }

        private void drwKompas(float angle, RectangleF rect)
        {
            if (_kompas != null)
            {
                _d2DContext.DrawBitmap(_kompas,
                    new RectangleF(rect.Left + rect.Width - rect.Height*0.22f, rect.Top + rect.Height*0.78f,
                        rect.Height*0.2f, rect.Height*0.2f), 1, BitmapInterpolationMode.Linear);
                  float x1 = (rect.Left + rect.Width - rect.Height*0.12f) + rect.Height*0.095f*(float)( Math.Sin(Yau/180.0*Math.PI));
                  float y1 = (rect.Top + rect.Height * 0.88f) - rect.Height * 0.095f * (float)(Math.Cos(Yau / 180.0 * Math.PI));
                  float x2 = (rect.Left + rect.Width - rect.Height * 0.12f) + rect.Height * 0.07f * (float)(Math.Sin(Yau / 180.0 * Math.PI));
                  float y2 = (rect.Top + rect.Height * 0.88f) - rect.Height * 0.07f * (float)(Math.Cos(Yau / 180.0 * Math.PI));



                  _d2DContext.DrawLine(new Vector2(x1, y1), new Vector2(x2, y2), TRBrshR, rect.Height/40);


                if (Speed != null)
                    if (Speed.Length ==3)
                        _d2DContext.DrawLine(
                            new Vector2(rect.Left + rect.Width - rect.Height * 0.12f, rect.Top + rect.Height * 0.88f),
                            new Vector2(rect.Left + rect.Width - rect.Height * 0.12f - rect.Height * 0.05f * Math.Min(Speed[0], 1), rect.Top + rect.Height * 0.88f - rect.Height * 0.05f * Math.Min(Speed[0], 1)), TRBrshG,
                            rect.Height / 150);
            }

        }

        public PictureBoxSizeMode SizeMode = PictureBoxSizeMode.Zoom;

        private Bitmap _bitmap;
        private Bitmap _kompas;
        private Device _device;
        private SharpDX.Direct2D1.DeviceContext _d2DContext;
        private SwapChain1 _swapChain;
        private Bitmap _d2DTarget;
        private SwapChainDescription1 _description;
        private SwapChainFullScreenDescription _descriptionFull;
        private Factory2 _dxgiFactory2;
        private BitmapProperties1 _properties;
        private Device2 _dxgiDevice2;
        private Adapter _dxgiAdapter;
        private SharpDX.Direct2D1.Device _d2DDevice;
        private Surface _backBuffer;
        private Device _defaultDevice;
        private SharpDX.Direct2D1.SolidColorBrush TRBrshW;
        private SharpDX.Direct2D1.SolidColorBrush TRBrshR;
        private SharpDX.Direct2D1.SolidColorBrush TRBrshG;
        private SharpDX.Direct2D1.SolidColorBrush TRBrshB;

        private SharpDX.Direct2D1.SolidColorBrush TRBrshWW;
        private SharpDX.Direct2D1.SolidColorBrush TRBrshRR;
        private SharpDX.Direct2D1.SolidColorBrush TRBrshGG;


        private SharpDX.DirectWrite.Factory _wrireFactory;
        private void Initdx()
        {
            _defaultDevice = new Device(DriverType.Hardware, DeviceCreationFlags.BgraSupport);
            _device = _defaultDevice.QueryInterface<Device1>();
            _dxgiDevice2 = _device.QueryInterface<Device2>();
            
       

            _dxgiAdapter = _dxgiDevice2.Adapter;


      

            _description = new SwapChainDescription1()
            {
                Flags = SwapChainFlags.GdiCompatible,
                Format = Format.B8G8R8A8_UNorm,
                Stereo = false,
                SampleDescription = new SampleDescription(1, 0),
                Usage = Usage.RenderTargetOutput,
                BufferCount = 2,
                Scaling = Scaling.None,
                SwapEffect = SwapEffect.FlipSequential,
            };

            _descriptionFull = new SwapChainFullScreenDescription()
            {
                
                Scaling = DisplayModeScaling.Centered
        
            };
            _dxgiFactory2 = _dxgiAdapter.GetParent<Factory2>();
            _wrireFactory = new SharpDX.DirectWrite.Factory();
            _d2DDevice = new SharpDX.Direct2D1.Device(_dxgiDevice2);
       
            _d2DContext = new SharpDX.Direct2D1.DeviceContext(_d2DDevice, DeviceContextOptions.EnableMultithreadedOptimizations);
            _properties = new BitmapProperties1(new PixelFormat(Format.B8G8R8A8_UNorm, AlphaMode.Premultiplied), 96, 96, BitmapOptions.Target | BitmapOptions.CannotDraw);
            _swapChain = _dxgiFactory2.CreateSwapChainForHwnd(_device, Handle, ref _description, _descriptionFull, null);
            _backBuffer = _swapChain.GetBackBuffer<Surface>(0);
            _d2DTarget = new Bitmap1(_d2DContext, _backBuffer, _properties);
            TRBrshW = new SolidColorBrush(_d2DContext, new Color4(1, 1, 1, 0.8f));
            TRBrshG = new SolidColorBrush(_d2DContext, new Color4(0.5f, 1, 0.5f, 0.7f));
            TRBrshR = new SolidColorBrush(_d2DContext, new Color4(1, 0.5f, 0.5f, 0.7f));

            TRBrshWW = new SolidColorBrush(_d2DContext, new Color4(1, 1, 1, 1f));
            TRBrshGG = new SolidColorBrush(_d2DContext, new Color4(0f, 1, 0f, 1f));
            TRBrshRR = new SolidColorBrush(_d2DContext, new Color4(1, 0f, 0f, 1f));
        
            TRBrshB = new SolidColorBrush(_d2DContext, new Color4(0, 0f, 0f, 0.5f));
            if (File.Exists("HeadingWeel.bmp"))
            {
                System.Drawing.Bitmap bbb = new System.Drawing.Bitmap("HeadingWeel.bmp");
                _kompas = LoadFromBitmap(_d2DContext, bbb);
            }


        }

        public void ShowImage(System.Drawing.Bitmap bitmap)
        {
            lock (_lo)
            {
                if (_bitmap != null) _bitmap.Dispose();
                _bitmap = LoadFromBitmap1(_d2DContext, bitmap);

            }
            Refresh();

        }

        public void ShowImage(byte[] bitmap, int w, int h, int stride)
        {
            lock (_lo)
            {
                if (_bitmap != null) _bitmap.Dispose();
                _bitmap = LoadFromBitmap2(_d2DContext, bitmap, w, h, stride);

            }
            Refresh();

        }

        private static Bitmap LoadFromBitmap1(RenderTarget renderTarget, System.Drawing.Bitmap bitmap)
        {
            var sourceArea = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);

            var bitmapProperties = new BitmapProperties(new PixelFormat(Format.B8G8R8A8_UNorm, AlphaMode.Premultiplied));

            var bitmapData = bitmap.LockBits(sourceArea, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppRgb);

            var b = new Bitmap(renderTarget, new Size2(bitmap.Width, bitmap.Height), bitmapProperties);
            b.CopyFromMemory(bitmapData.Scan0, bitmapData.Stride);
            bitmap.UnlockBits(bitmapData);

            return b;



        }

        private static Bitmap LoadFromBitmap2(RenderTarget renderTarget, byte[] bitmap, int w, int h, int stride)
        {

            var bitmapProperties = new BitmapProperties(new PixelFormat(Format.B8G8R8A8_UNorm, AlphaMode.Ignore));
            var b = new Bitmap(renderTarget, new Size2(w, h), bitmapProperties);
            b.CopyFromMemory(bitmap, stride);



            return b;



        }

        private static Bitmap LoadFromBitmap(RenderTarget renderTarget, System.Drawing.Bitmap bitmap)
        {


            var sourceArea = new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height);
            var bitmapProperties = new BitmapProperties(new PixelFormat(Format.R8G8B8A8_UNorm, AlphaMode.Premultiplied));
            var size = new Size(bitmap.Width, bitmap.Height);
            var stride = bitmap.Width * sizeof(int);
            using (var tempStream = new DataStream(bitmap.Height * stride, true, true))
            {
                var bitmapData = bitmap.LockBits(sourceArea, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                for (var y = 0; y < bitmap.Height; y++)
                {
                    var offset = bitmapData.Stride * y;
                    for (var x = 0; x < bitmap.Width; x++)
                    {
                        var B = Marshal.ReadByte(bitmapData.Scan0, offset++);
                        var G = Marshal.ReadByte(bitmapData.Scan0, offset++);

                        var R = Marshal.ReadByte(bitmapData.Scan0, offset++);

                        var A = 70;
                        if (R == 255 && G == 255 && B == 0)
                        {
                            A = 0;
                            B = G = R = 0;
                        }


                        var rgba = R | (G << 8) | (B << 16) | (A << 24);
                        tempStream.Write(rgba);
                    }
                }
                bitmap.UnlockBits(bitmapData);
                tempStream.Position = 0;
                return new Bitmap(renderTarget, new Size2(size.Width, size.Height), tempStream, stride, bitmapProperties);
            }
        }

        private Size _lsize;

        private void timer1_Tick(object sender, EventArgs e)
        {

        }


        public void Uninitialize()
        {

            _device.Dispose();
            _d2DContext.Dispose();
            _swapChain.Dispose();
            _d2DTarget.Dispose();
            _dxgiFactory2.Dispose();
            _dxgiDevice2.Dispose();
            _dxgiAdapter.Dispose();
            _d2DDevice.Dispose();
            _backBuffer.Dispose();
            _defaultDevice.Dispose();
        }

        private void timer1_Tick_1(object sender, EventArgs e)
        {
            if (_lsize != ClientSize)
            {
                lock (_lo)
                {
                    _lsize = ClientSize;
                    Uninitialize();
                    Initdx();
                }
                Refresh();
            }
        }

    }
}
